#ifndef CON_DETAIL_IOSTREAM_H
#define CON_DETAIL_IOSTREAM_H

#pragma once

#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/categories.hpp>
#include <iosfwd> // for std::streamsize

static const int CHILD = 0;
static const int PARENT = 1;
static const int NUM_HANDLES = 2;

// makeshift typedef so we don't have to include windows.h
typedef void* HANDLE;

namespace Con
{
	namespace detail
	{
		namespace boost = boost::iostreams;

		class IOStream : public boost::bidirectional
		{
			// flags used when the IOStream object refers to the current process console
			enum Flags
			{
				NONE = 0,
				REPRESENTS_DEFAULT_CONSOLE = 1,
				REDIRECTED_STD_HANDLES = 2
			};

			HANDLE hOutputs[NUM_HANDLES];
			HANDLE hInputs[NUM_HANDLES];
			
			Flags cFlags;

			// not implemented
			IOStream& operator=(const IOStream& other);

		public:
			// traits used by base classes
			typedef char char_type;
			typedef boost::bidirectional_device_tag category;

			// standard constructor for child processes
			IOStream(const HANDLE hIns[NUM_HANDLES], const HANDLE hOuts[NUM_HANDLES]);

			// constructor for the process' built-in console
			explicit IOStream(int);

			IOStream(const IOStream& other);

			~IOStream();

			std::streamsize write(const char* outBuf, std::streamsize count);

			std::streamsize read(char* inBuf, std::streamsize count);
		};

		typedef boost::stream_buffer<IOStream> IO;
	}
}

#endif
